#! /usr/bin/env python

##
##    This program is free software; you can redistribute it and/or modify
##    it under the terms of the GNU General Public License as published by
##    the Free Software Foundation; either version 2 of the License, or
##     ( at your option )  any later version.
##
##    This program is distributed in the hope that it will be useful,
##    but WITHOUT ANY WARRANTY; without even the implied warranty of
##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##    GNU General Public License for more details.
##
##    You should have received a copy of the GNU General Public License
##    along with this program; if not, write to the Free Software
##    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
##

import pygtk
pygtk.require('2.0')
import gtk, gobject, cairo
from gtk import gdk

# Create a GTK+ widget on which we will draw using Cairo
class Screen(gtk.DrawingArea):

    # Draw in response to an expose-event
    __gsignals__ = { "expose-event": "override" }

    def __init__(self):
        super(Screen,self).__init__()
        # gtk.Widget signals
        self.connect("button_press_event", self.button_press)
        self.connect("button_release_event", self.button_release)
        self.connect("motion_notify_event", self.motion_notify)
        self.connect("configure_event", self.configure) #resize
        self.connect("realize", self.realize)
        # More GTK voodoo : unmask events
        self.add_events(gdk.BUTTON_PRESS_MASK |
                        gdk.BUTTON_RELEASE_MASK |
                        gdk.POINTER_MOTION_MASK)
        self.cr = None

    # Handle the expose-event by drawing
    def do_expose_event(self, event):

        # Create the cairo context
        self.cr = self.window.cairo_create()
        self.hitpath = None #Is set later

        # Restrict Cairo to the exposed area; avoid extra work
        self.cr.rectangle(event.area.x, event.area.y,
                event.area.width, event.area.height)
        self.cr.clip()

        self.draw(self.cr, *self.window.get_size())


    def draw(self, cr, width, height):
	    pass

    def button_press(self,widget,event):
        pass
    def button_release(self,widget,event):
        pass
    def motion_notify(self,widget,event):
        pass
    def configure(self,widget,event):
        pass
    def realize(self,widget):
        pass        
# GTK mumbo-jumbo to show the widget in a window and quit when it's closed
def run(Widget):
    window = gtk.Window()
    
    #window.set_composited(True)
    window.connect("delete-event", gtk.main_quit)
    #window.connect("expose-event",transparent_expose)
    widget = Widget()
    window.connect('screen-changed', widget.screen_changed)
    widget.screen_changed(window)
    widget.show()
    window.add(widget)
    window.present()
    window.show_all()
    window.set_app_paintable(True)
    #widget.window.set_composited(True)
    gtk.main()

def transparent_expose(widget, event):
    cr = widget.window.cairo_create()
    cr.set_operator(cairo.OPERATOR_CLEAR)
    
    # Ugly but we don't have event.region
    region = gtk.gdk.region_rectangle(event.area)
    
    cr.region(region)
    cr.fill()
    
    return False



class CairoHScroll(Screen):

    def __init__(self):
        Screen.__init__(self)
        #gtk.gdk.flush()
        self.screen_changed(self)
        self.x = self.y = 10
        self.oxx = self.oyy = self.ox = self.oy = 0
        self.drag = False
        self.hit = False
        self.range = (14.0,75.0)
        self.value_range = self.value = 0.0
        self.set_app_paintable(True)
        self.connect('screen-changed', self.screen_changed)
        
    def realize(self,widget):
        pass
        #self.window.set_composited(True)
        #self.window.set_app_paintable(True)

        
    #Override the press event
    def button_press(self,widget,event):
        self.drag = True
        self.cr.append_path(self.hitpath) # re-gen the path
        self.hit = self.cr.in_fill(event.x, event.y) # Test it. Sweet.
        self.oxx = event.x - self.ox
        self.oyy = event.y - self.oy
        print self.hit
        
    def button_release(self,widget,event):
        self.drag = False
        
    def configure(self,widget,event):
        w,h = self.window.get_size()
        self.x = self.value * w

    def draw(self, cr, width, height):
        w,h = self.window.get_size()
        sx = sy = 24
        x,y = self.x - self.oxx,0 # self.y - self.oyy
        
        if x >= w - sx:
            x = w-sx
        if x < 0:
            x = 0

        self.value = float(x)/ (w - sx)
        self.value_range = self.value * (self.range[1] - self.range[0]) + self.range[0]
        print "Value:",self.value, self.value_range, "w.h", w,h

       #Make the window transparent
        #if supports_alpha == True:
        cr.set_source_rgba(1.0, 1.0, 1.0, 0.0)
        #else:
        #    cr.set_source_rgb(1.0, 1.0, 1.0) 
        
        cr.set_operator(cairo.OPERATOR_SOURCE)
        cr.paint()
        
        cr.move_to(5,y + sy/2-2)
        cr.line_to(w-5,y + sy/2-2)
        cr.line_to(w-5,y + sy/2+2)
        cr.line_to(5,y + sy/2+2)
        cr.close_path()
        cr.set_source_rgba(0.7,0.2,0,1.0)
        cr.stroke()
        
        cr.new_path()
        cr.move_to(x,y)
        cr.line_to(x+sx,y)
        cr.line_to(x+sx,y+sy)
        cr.line_to(x,y+sy)

        cr.close_path()
        cr.set_source_rgba(1,0,0,1)

        self.hitpath = cr.copy_path_flat() #record the path to use as a hit area.
        self.ox,self.oy = cr.get_current_point() # should get most left point of the knob here
        print self.ox,self.oy
        cr.fill() #consumes the path, so get it before the fill
        

        return False
        
    def motion_notify(self,widget,event):
        if self.hit and self.drag:
            self.x, self.y = event.x, event.y
            self.queue_draw()
            
    #If screen changes, it could be possible we no longer got rgba colors
    def screen_changed(self,widget, old_screen=None):
        screen = widget.get_screen()
        colormap = screen.get_rgba_colormap()
        if colormap == None:
            print 'Your screen does not support alpha channels!'
            colormap = screen.get_rgb_colormap()
            
            #supports_alpha = False
        else:
            print 'Your screen supports alpha channels!'
            #supports_alpha = True
        
        widget.set_colormap(colormap)
        
        return True

run(CairoHScroll)

